perm filename MTASRX.MAC[SS,SYS] blob sn#495374 filedate 1980-02-04 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00037 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00004 00002	IFNDEF TM10B, <TM10B=0>
C00006 00003
C00008 00004	MAG TAPE DEVICE DATA BLOCK
C00009 00005
C00011 00006	MAG TAPE STATUS BITS (MTS)
C00013 00007	INITIALIZE
C00015 00008
C00018 00009	IT IS POSSIBLE TO GET HERE AT UUO LEVEL WHILE CONTROL STILL CONNECTED TO THIS UNIT
C00021 00010	WE ARE NOW CONNECTED TO THE TRANSPORT
C00023 00011	THINK ABOUT REWINDING TRANSPORTS THAT HAVE BEEN SUBSEQUENTLY SELECTED
C00025 00012	COPY STATUS THAT LASTS ACROSS INTERRUPTS. DO NOT MODIFY S
C00027 00013	MTAPE
C00030 00014	SET 9-TRACK TAPE
C00032 00015
C00034 00016	OUTPUT UUO
C00037 00017
C00038 00018	HERE WHEN BLKI/BLKO COUNTS DOWN TO ZERO.
C00040 00019
C00041 00020	INTRD:				HERE FOR BUFFERED MODE INPUT INTERRUPT
C00043 00021
C00045 00022
C00047 00023	WB.1:	HLRZ	U,USEWRD
C00050 00024	HERE TO RECOVER FROM A READ ERROR
C00052 00025	ERREAD:	0
C00054 00026
C00056 00027	CALCULATE NUMBER OF 3" SECTIONS OF BLANK TAPE TO 
C00058 00028	IFN TM10B,<
C00060 00029	MORE ERROR CODE
C00062 00030	EXTERNAL WAIT1
C00065 00031	EXTERNAL NXCMR,PBUFSZ
C00067 00032
C00069 00033
C00071 00034	USEWRD:	0		LH STORE COMMAND ISSUED BY CONO MTC,
C00073 00035	DUMP MODE IO CONTROL FLAGS
C00075 00036
C00076 00037	
C00077 ENDMK
C⊗;
IFNDEF TM10B, <TM10B=0>
;SET TM10B=-1 TO ASSEMBLE FOR USE WITH DF10 DATA CHANNEL
IFE TM10B,<
TITLE MTASRX -MAGTAPE ROUTINES FOR PDP-10(TM-10A)
	INTERN	MTAINT,MTADDS,MTADDB
	EXTERN	MTALOC,MTLOC1,MTASAV
MTASRX:	ENTRY	MTASRX
>
IFN TM10B,<
TITLE MTASBX -MAGTAPE ROUTINES FOR PDP-10(TM-10B)
	INTERN	MTBINT,MTBDDS,MTBDDB
	EXTERN	MTIOC,MTCCW,MTBSAV
MTASBX:	ENTRY	MTASBX
>
SUBTTL T.WACHS/TW/CMF  TS  28 DEC 71  V541
	XP	VMTASR,541	;DEFINE VERSION NUMBER FOR LOADER STORAGE MAP
	;MODIFIED 29-SEP-69 J. SAUTER, SANDERS


IFNDEF FTSACCT,<FTSACCT==0>	;DEC STANDARD IS 0
IFNDEF MTRRCK,<MTRRCK==0>	;DEC STANDARD IS 0

;DISPATCH TABLE
EXTERN REGSIZ
	JRST	REGSIZ		;BUFFER SIZE CAN BE GOTTEN FROM DDB
	JRST	MTAINI
	JRST	MTASEC		;CALLED IF HUNG DEVICE
MTADSP:	JRST	MTAREL		;RELEASE
	JRST	MTCLOS		;CLOSE
	JRST	MTOUT
	JRST	MTIN
	JRST	CPOPJ1		;ENTER
	JRST	CPOPJ1		;LOOKUP
	JRST	MTDMPO
	JRST	MTDMPI
	POPJ	P,		;USETO
	POPJ	P,		;USETI
	POPJ	P,		;UGETF
	JRST	CPOPJ1		;RENAME
	POPJ	P,		;CLOSE INPUT
	POPJ	P,		;UTPCLR
	JRST	MTAP0

MTC=340
MTS=344

;MTACHN=FLAG CHANNEL
;MTDCHN=DATA CHANNEL
;MTFLAG=10*MTACHN + 400
;MTBOTH=10*MTACHN+MTDCHN
;MTALOC=40 + 2*MTDCHN
;MTLOC1=MTALOC+1
	INTERNAL	MTAINT
	EXTERNAL	ERROR,TIME,JOB
	EXTERNAL	ADVBFE,ADVBFF,MTFLAG,MTBOTH,SETACT,CLRACT,WSYNC
	EXTERNAL	STDENS,SETIOD,MTREQ,MTAVAL,OUT
	EXTERNAL	CPOPJ,CPOPJ1,PIOMOD,PUNIT,MTWAIT,COMCHK,HNGSTP
	EXTERNAL	PIOFF,PION,ADRERR,MTSIZ,STOIOS,SETHNG

WRLOK==20000			;THIS TRANSPORT IS WRITE LOCKED
HASCTL==40000			;THIS TRANSPORT HAS CONTROLLER
COMPAT==100000			;IBM COMPATABLE 9-TRACK
RRCHK==200000			;USER WANTS TO RE-READ CHECK EACH RECORD
MTREW==400000			;MAGTAPE IS REWINDING


MTTRY==10			;NO. OF TIMES TO RETRY ON AN ERROR
QUANT==10			;NO. OF RECORDS TO READ UNINTERRUPTED
MTWTTM=4000		;TIME TO WAIT FOR STATUS.  INCREASE IF CPU
			;SPEED INCREASES (WILL GET UNDESERVED DEVICE OK
			;IF TOO SMALL).
NOISE==3		;ANY RECORD READ IN ERROR WITH .LT. NOISE
			;WORDS IS CONSIDERED "NOISE" AND IGNORED

;MAG TAPE DEVICE DATA BLOCK
MTBDDB:
MTADDB:
	PHASE	0
DEVNAM:	SIXBIT	/MTA0/
DEVCHR:	XWD	↑D5*HUNGST,MTSIZ+1
DEVIOS:	Z
DEVSER:	MTADSP
$MODE=1←D+1←DR+1←B+1←IB+1←I+1←AL+1←A
DEVMOD:	XWD	DVIN+DVOUT+DVLNG+DVMTA,$MODE
DEVLOG:	Z
DEVBUF:	Z
DEVIAD:	XWD	R,0
DEVOAD:	XWD	R,0
DEVSTS:	Z
DEVSTA:	XWD	.TYMTA!DEPLEN,0	;UNSPOOLED, VAR BUFFER SIZE
DEVXTR:	Z

	XP	MTADDS,.
	XP	MTBDDS,.
	DEPHASE

REPEAT 0,<

MEANING OF MTC BITS

15-17	NEXT UNIT NUMBER

18-20	CURRENT UNIT NUMBER

21	PARITY	1=ODD, 0=EVEN
22	CORE DUMP 0=4 BYTES, 1=4.5 BYTES

23-26	FUNCTIONS
	0	NO-OP  -CLEAR INTERRUPT FLAGS
	1	REWIND
	2	READ
	3	READ/COMPARE
	4	WRITE
	5	WRITE END-OF-FILE
	6	SPACE FORWARD ONE OR MORE RECORDS
	7	SPACE REVERSE ONE OR MORE RECORDS
	10	NO-OP  INTERRUPT WHEN XPORT IDLE
	11	REWIND AND UNLOAD
	12	READ ACCROSS RECORD BOUNDARIES
	13	READ/COMPARE ACROSS RECORD BOUNDARIES
	14	WRITE WITH LONG EOR  GAP
	15	WRITE 3 INCHES OF BLANK TAPE
	16	SPACE TO END-OF-FILE
	17	SPACE REVERSE TO END-OF-FILE

27	NEXT UNIT ENABLE

28-29	DENSITY
	00	200BPI
	01	556BPI
	10	800BPI
	11	RESERVED (CURRENTLY 800BPI)

30-32	FLAG PIA
33-35	DATA PIA
>
;MAG TAPE STATUS BITS (MTS)

HUNG==1B18		;*TRANSPORT HUNG
REW==1B19		; TRANSPORT IS REWINDING
BOT==1B20		; AT BEGINNING OF TAPE

ILLOP==1B21		;*ILLEGAL OPERATION
PERROR==1B22		; PARITY ERROR
EOF==1B23		; END OF FILE

EOT==1B24		; END OF TAPE
RCERR==1B25		; READ-COMPARE ERROR
RLINC==1B26		; RECORD LENGTH INCORRECT

DLATE==1B27		; DATA LATE
BDTAPE==1B28		; BAD TAPE (DATA IN EOR)
JBDONE==1B29		;*JOB DONE

IDLE==1B30		; TRANSPORT IDLE
CHANER==1B31		; CHANNEL ERROR (TM10B ONLY)
WRLK==1B32		; WRITE LOCK

CHAN7==1B33		; 7-CHANNEL TRANSPORT
NXUNIT==1B34		;*(IF ENABLED) NEXT UNIT STATUS AVAILABLE
DATARQ==1B35		;*(ON DATA PIA) DATA REQUEST

;LH CONI BITS
CWPAR==1B11		;CONTROL WD PARITY ERR (TM10B)
CHANXM==1B12		;CHAN NXM (TM10B)
DTPAR==1B13		;*CHAN DETECTED CORE PARITY ERR (TM10B)
WCWDON==1B14		;*WRITE CONTROL WORD DONE (TM10B)
;INITIALIZE
MTAINI:	SETZM	REMNDR
	MOVEI	T1,INTIGN	;IGNORE INTERRUPTS
	MOVEM	T1,INTSW
	HLLZS	MTAINT
	CONO	MTC,0		;TURN OFF MTC
IFE TM10B,<
	MOVE	T1,[JSR MTDEND]	;SET UP END-CONDITION
	MOVEM	T1,MTLOC1	;FOR BLKI/BLKO
>
IFN TM10B,<
	MOVEI	T1,PNTR
	MOVEM	T1,MTIOC	;SET INITIAL CHANNEL CONTROL WORD
>
	SETZM	LVFLAG		;INDICATE NOT IN DUMP MODE
	POPJ	P,

;CLOSE
MTCLOS:	TLNN	F,OUTPB		;OUTPUT BEEN DONE?
	POPJ	P,		;NO. GO AWAY
	LDB	T1,PIOMOD
	CAIGE	T1,DR		;DUMP MODE?
	PUSHJ	P,OUT		;NO. EMPTY LAST PARTIAL BUFFER
	PUSHJ	P,WSYNC		;WAIT FOR IO TO STOP
	HRRI	M,3		;WRITE 2 ENDS-OF FILE
	PUSHJ	P,MTAP1
	TRNE	S,IOIMPM	;WRITE LOCK?
	POPJ	P,		;YES! RETURN
	PUSHJ	P,SETACT
	PUSHJ	P,WSYNC
	HRRI	M,3
	PUSHJ	P,MTAP1
	PUSHJ	P,SETACT
	PUSHJ	P,WSYNC
	HRRI	M,7		;AND BACKSPACE OVER ONE OF THEM
	PUSHJ	P,MTAP1
	PUSHJ	P,SETACT
	PUSHJ	P,WSYNC
	TRZ	S,IODEND	;CLEAR EOF AFTER CLOSE SINCE
				; PROGRAMS EXPECT IT ON INPUT ONLY
	PJRST	STOIOS		;STORE S AND EXIT

;ATTEMPT RECOVERY FROM HUNG DEVICE TIME OUT IF WRITE IN PROGRESS
;HERE FROM -1(DISPATCH TABLE)

MTASEC:	CONI	MTS,HNGMTS	;SAVE STATUS IF RECEIVE HUNG DRIVE
	CONI	MTC,HNGMTC
	HLRZ	T1,USEWRD	;GET COMMAND
	MOVEM	T1,HNGFNC	;SAVE FUNCTION
	ANDI	T1,017000	;MASK FUNCTION
	AOS	RECCNT		;COUNT OCCURENCE
IFN FTTRACK,<
	MOVE	T2,TIME
	MOVEM	T2,TIMHNG	;NOTE TIME OF OCCURENCE
>
INTERNAL FTSACCT
IFN FTSACCT,<
EXTERNAL JBAMT1,HNGTST
	AOS	JBAMT1(J)	;ACCOUNT FOR 2 MORE SECONDS OF USE
	PUSHJ	P,HNGTST	;IS MTA HUNG ?
>
	JUMPGE	S,HUNGTP	;IF NOT REWINDING
	TLNN	S,HASCTL	;DO WE HAVE CONTROL?
	POPJ	P,		;DON'T RELEASE CONTROL WE DON'T HAVE
	JRST	RELTAP		;RELEASE TAPE CONTROL & PRINT MESSAGE

HUNGTP:	CAIE	T1,004000	;WRITE?
	CAIN	T1,014000	;OR WRITE WITH LONG EOR?
	JRST	HNGWRT		;YES. ATTEMPT RECOVERY
HNGTPC:	TRO	S,IODERR	;SET DEVICE ERROR
	MOVEM	S,DEVIOS(F)
	JRST	RELTAP		;RELEASE CONTROL AND EXIT TO
				; GIVE HUNG DEVICE MESSAGE

HNGWRT:	HRRZ	T1,INTSW
	CAIE	T1,INTWR
	CAIN	T1,INTDMP	;ARE WE IN ERROR RECOVERY CODE?
	JRST	HNGW.1		;NO.
	JRST	HNGTPC		;YES. GIVE HUNG DEVICE
HNGW.1:	MOVEI	T1,FRCREC
	MOVEM	T1,INTSW	;FORCE ERROR RECOVERY
	PUSHJ	P,SETACT	;SET IOACT AND HUNG COUNT AGAIN
	HLRZ	T1,USEWRD	;GET COMMAND
	TRZ	T1,017400	;MASK FUNCTION+NEXT UNIT ENABLE
	IORI	T1,010000	;FORM NOP
	CONO	MTC,(T1)	;FORCE AN INTERRUPT TO GET TO
				; ERROR RECOVERY
	JRST	CPOPJ1		;MISS HUNG MESSAGE
				;EXIT HUNG TIMEOUT


;HERE TO FORCE ERROR RECOVERY AT INTERRUPT LEVEL AFTER HUNG DEVICE

FRCREC:	TRO	S,IODERR	;ENSURE THAT ERROR IS NOTED
				; SO ERRCK WILL CALL RECOVERY CODE
	JRST	@INTSW1		;DISPATCH TO ORIGINAL HANDLER
;IT IS POSSIBLE TO GET HERE AT UUO LEVEL WHILE CONTROL STILL CONNECTED TO THIS UNIT
;AND AN INTERRUPT PENDING FROM A PREVIOUS MTAPE, SO MUST WAIT
;FOR MTAPE TO BE FINISHED ON THIS UNIT.

DLYCTL:	MOVEI	T1,IOACT	;FLAG THAT DEVICE IS EXPECTING AN INTERRUPT
	MOVSI	S,HASCTL	;WAIT FOR CONTROL TO BE FREE
	CONO	PI,PI.OFF	;TURN OFF PI SYSTEM
				; S
	TDNN	S,DEVIOS(F)	;IS THIS UNIT CONNECTED TO CONTROL?
	JRST	GETCTL		;NO, THEN GRAB IT
	IORM	T1,DEVIOS(F)	;YES, SO FLAG DEVICE AS ACTIVE
	CONO	PI,PI.ON	;ALLOW INTERRUPTS AGAIN
	PUSHJ	P,SETHNG	;SET HUNG TIME OUT
	PUSHJ	P,WSYNC		;WAIT FOR INTERRUPT (ON SPACING OPERATION)
	JRST	DLYCTL		;NOW TRY AGAIN

;GET CONTROL OF MAG TAPE CONTROLLER AND CONNECT IT TO A TRANSPORT

GETCTL:	CONO	PI,PI.ON	;TURN PI BACK ON
	MOVSI	S,HASCTL	;DO WE OWN THE CONTROL?
	TDOE	S,DEVIOS(F)
	STOPCD	CPOPJ
	AOSE	MTREQ		;NO, GET IT.
	PUSHJ	P,MTWAIT
	PUSHJ	P,STOIOS
	LDB	T1,PUNIT	;GET UNIT NUMBER FROM DDB.
	LSH	T1,17		;SET UP CONO
	CONO	MTC,10000(T1)	;SELECT UNIT.
	MOVEI	T2,MTWTTM
	CONSO	MTS,HUNG!JBDONE!REW	;WAIT FOR STATUS
	SOJG	T2,.-1
	JUMPE	T2,GETC6	;NO STATUS??
	PUSHJ	P,SETPST	;COPY NON-TRANSITORY  STATUS INTO S
	JUMPGE	S,GETC3		;JUMP IF NOT REWINDING.
INTERN FTSLEEP
IFE FTSLEEP,<
	PUSHJ	P,SETACT	;PRETEND I/O ACTIVE
	PUSHJ	P,CLOKRQ	;ENTER CLOCK RQ FOR THIS UNIT
	PUSHJ	P,RELCTL	;RELEASE CONTROL
	PUSHJ	P,WSYNC		;WAIT FOR REWIND TO FINISH
	JRST	GETCTL		;TRY AGAIN WHEN REWIND DONE

>	IFN FTSLEEP,<EXTERN SLEEP
	PUSHJ	P,RELCTL	;RELEASE CONTROL
	MOVE	J,JOB		;GET JOB # FOR SLEEP
	MOVEI	T1,2
	PUSHJ	P,SLEEP		;SLEEP 2 SECONDS -CAN BE SWAPPED
	JRST	GETCTL		;TRY AGAIN
>
;WE ARE NOW CONNECTED TO THE TRANSPORT

GETC3:	TRNN	S,IODERR	;IS TRANSPORT SICK?
	JRST	GETC2		;NO.
GETC6:	PUSHJ	P,RELCTL	;YES, RELEASE CONTROL
	PUSHJ	P,HNGSTP	;PRINT MESSAGE
	JRST	GETCTL		;ON "CONT" TRY AGAIN.

GETC2:	TLNE	S,COMPAT	;IBM 360 COMPATABILITY MODE?
	JRST	GETC4		;YES.
	LDB	U,[POINT 2,S,28]
	JUMPN	U,GETC7		;USE DENSITY IF NOT 0
	LDB	U,[POINT 2,S,10]	;USER CHANGED DEFAULT DENSITY?
	JUMPN	U,GETC7		;DENSITY=0?
	MOVEI	U,STDENS	;YES, USE STANDARD
GETC7:	SUBI	U,1
	LSH	U,6
	TRNN	S,IOPAR		;ODD PARITY?
	TRO	U,40000		;YES.
	CONSO	MTS,CHAN7	;7-CHANNEL TRANSPORT?
	TRO	U,20000		;NO, SET 4.5 BYTE MODE
GETC5:	LDB	T2,PUNIT
	DPB	T2,[POINT 3,U,20]
	CONO	MTC,(U)		;CLEAR CONTROLLER FLAGS
	TRO	U,MTBOTH	;SET UP BOTH PI CHANNELS
	MOVEI	T1,HUNG!ILLOP!JBDONE!CHANER
	HRRM	T1,MTAINT	;SET UP INTERRUPT MASK
	MOVEI	T1,QUANT	;SET UP PROTECT TIME
	MOVEM	T1,QUANTM
	POPJ	P,		;RETURN

GETC4:	MOVEI	U,40300		;800 BPI, ODD PARITY, 4 BYTE MODE
	JRST	GETC5

;HERE TO RELEASE HARDWARE, THEN SOFTWARE
RELTAP:	PUSHJ	P,MTADIS	;CLEAR THE HARDWARE (CONO MTC)

RELCTL:				;RELEASE CONTROL
	TLZN	S,HASCTL	;DO WE HAVE IT?
	STOPCD	STOIOS		;NO. ERROR
	SOSL	MTREQ		;YES, RETURN IT
	SETOM	MTAVAL
	JRST	STOIOS
;THINK ABOUT REWINDING TRANSPORTS THAT HAVE BEEN SUBSEQUENTLY SELECTED

IFE FTSLEEP,<
CLOKRQ:	LDB	T1,PUNIT
	LSH	T1,14		;SEPARATE REQUEST FOR EACH REWINDING TRANSPORT
	IOR	T1,[XWD CLOK,1]	;CHECK EVERY CLOCK TICK
	CONO	PI,PIOFF
	IDPB	T1,CLOCK
	CONO	PI,PION
	POPJ	P,

CLOK:	PUSHJ	P,REWCK		;CHECK TRANSPORT
	PUSHJ	P,CLOKRQ	;STILL REWINDING
	POPJ	P,		;REACHED BOT

REWCK:	PUSHJ	P,GDVDAT	;GET F FROM UNIT NUMBER IN T1
	JSP	U,ERROR		;THERE IS NONE -- ERROR.
	JUMPGE	S,CPOPJ1	;JUMP IF NO LONGER REWINDING
	SKIPL	MTREQ		;ANYONE USING CONTROLLER?
	JRST	STOIOS		;YES, WAIT UNTIL LATER(RESET HUNG TIME)
	MOVEI	U,10000
	DPB	T1,[POINT 3,U,20]
	CONO	MTC,(U)		;REQUEST NEXT UNIT STATUS
	MOVEI	T2,MTWTTM
	CONSO	MTS,HUNG!BOT!REW
	SOJG	T2,.-1
	JUMPE	T2,CPOPJ	;JUMP IF STATUS NOT GENERATED.
	PUSHJ	P,SETST		;COPY STATUS INTO S(RESET HUNG TIME)
	JUMPL	S,CPOPJ		;JUMP IF STILL REWINDING.
	PUSHJ	P,SETIOD
	PUSHJ	P,CLRACT
	AOS	(P)		;DONT INSERT ANOTHER CLOCK REQUEST
	POPJ	P,
>
;COPY STATUS THAT LASTS ACROSS INTERRUPTS. DO NOT MODIFY S
;BITS THAT ARE MEANINGFUL ONLY AT INTERRUPT TIME E.G.EOF

SETPST:	TDZ	S,[XWD MTREW!WRLOK,IOBOT!IOTEND!IODERR]
	CONI	MTS,T1
	JRST	SETS.1

;COPY ALL STATUS OF MTC INTO IOS. USE AT INTERRUPT LEVEL

SETST:	TDZ	S,[XWD MTREW!WRLOK,IOBOT!IOTEND!IODTER!IODEND!IODERR!IOBKTL]
	CONI	MTS,T1
	MOVEM	T1,CNIMTS
	TRNE	T1,PERROR!BDTAPE	;PARITY ERROR OR BAD TAPE?
	TRO	S,IODTER	;YES.
	TRNE	T1,EOF		;END-OF-FILE?
	TRO	S,IODEND	;YES.
SETS.1:	TRNE	T1,REW!BOT	;AT BOT OR NEARLY?
	TRO	S,IOBOT		;YES.
	TRNE	T1,EOT		;AT EOT?
	TRO	S,IOTEND	;YES.
IFN TM10B,<
	SKIPN	CHNEWD		;CORE PARITY ERROR?
>
	TRNE	T1,DLATE!ILLOP!HUNG!CHANER
	TRO	S,IODERR
	TRNE	T1,REW		;STILL REWINDING?
	TLO	S,MTREW		;YES.
	TRNE	T1,WRLK		;IS TRANSPORT WRITE LOCKED?
	TLO	S,WRLOK		;YES.
	TRNN	S,IODERR!IODTER	;ANY ERRORS?
	JRST	STOIOS		;NO.
	MOVEM	T1,MTSERR	;YES. SAVE STATUS
	AOS	MTSCNT		;COUNT ERROR
	JRST	STOIOS

;BUILD F FROM UNIT NUMBER IN T1

GDVDAT:	MOVEI	F,MTADDB
GDVDT1:	MOVE	S,DEVIOS(F)
	HLRZ	T2,DEVNAM(F)
	CAIE	T2,(SIXBIT /MTA/)
	POPJ	P,
	LDB	T2,PUNIT
	CAMN	T2,T1
	JRST	CPOPJ1
	HLRZ	F,DEVSER(F)
	JUMPN	F,GDVDT1
	POPJ	P,
;MTAPE
MTAP0:	TRNE	M,100		;SETTING 7 TRACK MODE?
	JRST	SET9TK		;YES
IFN MTRRCK,<
	TRNE	M,200		;SETTING RE-READ MODE?
	JRST	SETRRD		;YES.>

INTERNAL FTSACCT
IFN FTSACCT,<
EXTERNAL PJOBN,JBAMT2
	LDB	J,PJOBN		;GET JOB NUMBER
	AOS	JBAMT2(J)	;ACCOUNT FOR ONE MORE MTAPE
>
MTAP:
MTAP1:	PUSHJ	P,DLYCTL	;GET CONTROL FOR THIS TAPE
MTAP3:	TRZ	U,7		;NO DATA TRANSFER
IFN TM10B,<
	SETZM	PNTR		;PNTR=0. DISCONNECT CHANNEL AFTER 1 OP
>
;CALL MTAPC IF DATA PIA AND PNTR MUST REMAIN INTACT
MTAPC:	HRRZ	T1,M
	ANDI	T1,17		;GET FUNCTION
	ROT	T1,-1		;TRANSLATE FROM TABLE
	SKIPL	T1
	SKIPA	T1,MTPTBL(T1)
	HLRZ	T1,MTPTBL(T1)
	TRZE	T1,100		;MOVE TAPE BACKWARD?
	TRNN	S,IOBOT		;YES, TAPE AT LOAD POINT OR REWINDING?
	TRNN	T1,-1		;OR NO-OP?
	JRST	RELTAP		;YES, RELEASE CONTROLLER AND EXIT
	TRZE	T1,200		;SKIP TO LOGICAL EOT?
	JRST	LEOT		;YES
	TRNE	T1,1000		;SKIP FILE?
	JRST	SKFILE		;YES.
	TRNE	T1,2000		;BACKSPACE FILE?
	JRST	BKFILE		;YES.
	TRZN	T1,400		;TRY TO WRITE TAPE?
	JRST	MTAGO		;NO.
	TLNE	S,WRLOK		;YES, WRITE LOCKED?
	JRST	WRLOCK		;YES, SET IOIMPM AND EXIT
MTAGO:	DPB	T1,[POINT 4,U,26]	;PUT FUNCTION INTO COMMAND
	HRLZM	U,USEWRD	;SAVE COMMAND
	MOVEI	T1,INTSP	;SET INTERRUPT SWITCH
	MOVEM	T1,INTSW
	MOVEM	R,USEPRG
MTCGO:	MOVEM	U,CNOMTC	;SAVE CONO
IFN TM10B,<
	SETZM	CHNEWD		;CLEAR ERROR WORD
	DATAO	MTS,[MTIOC]	;SET ICWA
>
	CONO	MTC,(U)		;ISSUE COMMAND
	POPJ	P,		;AND RETURN.


;SET 9-TRACK TAPE
SET9TK:	TRNE	M,1
	TLOA	S,COMPAT	;SET IBM COMPAT.
MTAREL:	TLZ	S,COMPAT	;NOT IBM COMPAT
	PUSHJ	P,STOIOS
	PJRST	WAIT1
IFN MTRRCK,<
SETRRD:	TRNE	M,1
	TLOA	S,RRCHK		;SET TO DO RE-READ CHECKING
	TLZ	S,RRCHK		;STOP DOING RE-READ CHECKING
	JRST	STOIOS>

;SKIP TO LOGICAL EOT
LEOT:	TRNE	S,IOBOT		;TAPE AT BOT?
	JRST	LEOT2		;YES. DONT BACKSPACE
	PUSHJ	P,MTAGO		;BACKSPACE RECORD
	PUSHJ	P,DLYCTL	;WAIT FOR IT.
LEOT2:	PUSHJ	P,SKFILE	;SKIP A FILE
	TRNE	S,IOTEND	;EOT?
	POPJ	P,		;YES. EXIT
	HRRI	M,6		;SKIP A RECORD
	PUSHJ	P,MTAP
	PUSHJ	P,DLYCTL	;WAIT FOR IT.
	TRNN	S,IODEND!IOTEND	;END OF FILE SEEN?
	JRST	LEOT2		;NO. SKIP TO NEXT FILE
	TRNE	S,IOTEND	;EOT SEEN?
	POPJ	P,		;NO BACKSPACE
	HRRI	M,7		;YES. BACKSPACE RECORD
	JRST	MTAP3

MTPTBL:	XWD	101,0		;REW,NOP
	XWD	405,0		;WRITE EOF,
	XWD	0,0
	XWD	107,6		;BACKSPACE REC,SKIP REC
	XWD	11,207		;REW&UNLOAD,LOG EOT
	XWD	415,0		;WRITE BLANK TAPE,
	XWD	0,0
	XWD	2117,1016	;BACK FILE,SKIP FILE


;THIS CODE REPLACES FUNCTION 16 SO THAT ONE USER CANNOT
;LOCK UP THE CONTROL

SKFILE:	PUSHJ	P,SKPSET	;SET TO SKIP QUANT RECORDS
	HRRI	M,6		;SKIP RECORD
	PUSHJ	P,MTAPC
	PUSHJ	P,DLYCTL	;WAIT
	TRNN	S,IODEND!IOTEND	;EOF OR EOT?
	JRST	SKFILE		;NO, CONTINUE
	JRST	RELTAP

;THIS CODE REPLACE FUNCTION 17 SO THAT ONE USER CANNOT
;LOCK UP THE CONTROL

BKFILE:	PUSHJ	P,SKPSET	;SET TO BACKSPACE QUANT RECORDS
	HRRI	M,7		;BACKSAPCE RECORD
	PUSHJ	P,MTAPC
	PUSHJ	P,DLYCTL
	TRNN	S,IOBOT!IODEND	;EOF OR BOT?
	JRST	BKFILE		;NO,CONTINUE
	JRST	RELTAP
SKPSET:
IFE TM10B,<
	MOVSI	T2,(BLKO MTC,)
	HRRI	T2,PNTR
	MOVEM	T2,MTALOC	;SET BLKO FOR 1 INTERRUPT/RECORD
>
	MOVNI	T1,QUANT
	HRLZM	T1,PNTR		;ALLOW QUANT INTERRUPTS BEFORE JBDONE
	POPJ	P,
;OUTPUT UUO
MTOUT:	PUSHJ	P,DLYCTL	;GET CONTROL, SETUP U
	TLNE	S,WRLOK		;WRITE LOCKED?
	JRST	WRLOCK		;YES, SET IOIMPM AND EXIT
	HRLZM	U,USEWRD	;SAVE FUNCTION
				;IN CASE 0-WORD REQUEST
	TLO	S,IO		;NO, INDICATE OUTPUT
	MOVEI	T2,INTWR	;SET INTERRUPT SWITCH
	MOVEM	T2,INTSW
MTOUT1:	MOVEI	T1,@DEVOAD(F)	;ADDRESS OF BUFFER
	HRRZ	T2,1(T1)	;WORD COUNT
	ADD	T2,DEVOAD(F)	;TOP ADR
	HLRZ	T3,R		;TOP LEGAL ADR
	CAILE	T3,(T2)		;IS IT LEGAL?
	JRST	MTOUT3		;YES
	TRO	S,IOBKTL	;NO, LIGHT ERROR BIT
	JRST	IOSTOP		;AND LEAVE
MTOUT3:

INTERNAL FTSACCT
IFN FTSACCT,<
EXTERNAL PJOBN,JBAMT3
	LDB	J,PJOBN
	MOVE	T2,1(T1)
	ADDM	T2,JBAMT3(J)	;ACCUMULATE COUNT OF WORDS WRITTEN
>
	MOVN	T2,1(T1)	;-WORD COUNT
	HRL	T1,T2		;IN LH OF COMMAND
	AOJG	T1,ADVOUT	;SKIP IF 0 WORDS
MTOUT2:	TRO	U,4000		;FUNCTION = WRITE
	TRZ	U,10000		;WITHOUT LONG EOR GAP
	MOVSI	T2,(BLKO MTC,)	;SETUP BLKO
MTDTGO:	MOVEM	T1,PNTR		;SAVE BLKI/BLKO POINTER
	MOVEM	T1,SVPNTR
	MOVEI	T1,MTTRY	;INITIALIZE ERROR COUNTER
	TLNN	S,IO		;READING?
	LSH	T1,1		;DOUBLE # OF TRIES
	MOVNM	T1,ERCNT
IFE TM10B,<
	HRRI	T2,PNTR		;BLKI/BLKO PNTR
	MOVEM	T2,MTALOC	;INTO INTERRUPT LOC
>
	HRLZM	U,USEWRD	;SAVE COMMAND
	MOVEM	R,USEPRG	;SAVE R
	MOVE	T1,INTSW
	MOVEM	T1,INTSW1	;SAVE CURRENT DISPATCH
	TRO	S,IOACT		;SETACT CLEARS IOW
	PUSHJ	P,STOIOS
	PUSHJ	P,MTCGO		;START IO AND SAVE CONO
	SKIPN	LVFLAG		;IS THIS FIRST TIME THRU FOR THIS CALL(AT UUO LEVEL)
	POPJ	P,		;NO. EXIT THIS INTERRUPT
	SETZM	LVFLAG		;YES. RESET FIRST TIME FLAG
	PUSHJ	P,WAIT1		;WAIT AT UUO LEVEL FOR INTERRUPT LEVEL IO
	SKIPE	BADCOM		;IO DONE(WAIT OVER)-ANY LIST ERRORS?
	JRST	ADRERR		;YES. REPORT THEM
	POPJ	P,		;NO. RETURN TO USER

;INPUT UUO
MTIN:	PUSHJ	P,DLYCTL	;SETUP U FOR THIS DRIVE
	TLZ	S,IO		;INPUT
	MOVEI	T2,INTRD	;SET INTERRUPT SWITCH
	MOVEM	T2,INTSW
MTIN1:	SETCM	T1,@DEVIAD(F)	;-LARGEST POSSIBLE WRD CNT
	HRRI	T1,@DEVIAD(F)	;STARTING ADDRESS
	ADD	T1,[XWD 2,1]	;MAKE REAL IOWD
MTIN2:	TRO	U,2000		;FUNCTION = READ
	MOVSI	T2,(BLKI MTC,)	;SETUP BLKI
	JRST	MTDTGO		;GO START TAPE

;HERE WHEN BLKI/BLKO COUNTS DOWN TO ZERO.
IFE TM10B,<

MTDEND:	0
	CONO	MTS,1		;ISSUE FUNCTION STOP
	JEN	@MTDEND
>


IFN TM10B,<
MTBIN0:	SKIPA	T1,MTBSAV
>
MTBINT:
MTAINT:	CONSO	MTS,0		;HERE TO CHECK FOR MAG TAPE INT.
	JRST	.-1
IFE TM10B,<
	JSR	MTASAV		;SAVE REGS, SET UP PDL
>
IFN TM10B,<
	CONSZ	MTS,HUNG!ILLOP!JBDONE	;CHAN ERROR ONLY?
	JRST	MTBIN2		;NO
	MOVEM	T1,MTBSAV	;YES. SAVE AN AC
	CONI	MTS,T1		;CONI
	TLNN	T1,(WCWDON!DTPAR)	;INTERRUPT FOR TM10B?
	JRST	MTBIN0		;NO, CONTINUE DOWN CONSO CHAIN
	MOVE	T1,MTBSAV	;YES
MTBIN2:	JSR	MTBSAV		;SAVE AC'S, SET UP PDL
>
	CONI	MTC,T1		;READ STATUS
	MOVEM	T1,CNIMTC	;SAVE STATUS
	HRRM	T1,USEWRD
	MOVE	R,USEPRG
	LDB	T1,[POINT 3,T1,20]
	PUSHJ	P,GDVDAT	;GENERATE F FOR INTERRUPTING TRANSPORT
	  JRST	MTADIS		;NO SUCH TRANSPORT -- IGNORE
				;(PROBABLY OPERATOR PLAYING WITH DIALS)
	LDB	T2,[POINT 3,USEWRD,2]
	CAME	T1,T2		;IS IT THE TRANSPORT WE EXPECTED?
	JRST	MTADIS		;NO, IGNORE (SAME CAUSE)
				;WE WILL GET HUNG DEVICE EVENTUALLY.
	TLNN	S,HASCTL	;WE HAD BETTER HAVE THE CONTROLLER
	STOPCD	.+1		;WE DONT!!
IFN FT5UUO,<
	CONI	MTS,DEVSTS(F)	;SAVE STATUS FOR USER OR DIAGNOSTIC USE
>
	PUSHJ	P,SETST		;SET UP STATUS IN S
	JRST	@INTSW		;DISPATCH-INTIGN INITIALLY

INTX1:
	PUSHJ	P,CLRACT
	TLZE	S,IOW
	PUSHJ	P,SETIOD	;NOTE WE DO NOT RELEASE CONTROLLER
INTIGN:
INTXIT:	PUSHJ	P,STOIOS	;STORE S
MTADIS:	HRRZ	U,USEWRD	;GET INTERRUPT STATUS
	ANDI	U,760700	;TURN OPERATION TO A NOP.
	PUSHJ	P,MTCGO		;GO DO THE NOP (WITH PIA=0)
	HLLZS	MTAINT		;NOW DISABLE SOFTWARE
	POPJ	P,


INTRD:				;HERE FOR BUFFERED MODE INPUT INTERRUPT
	JSR	ERRCK		;CHECK FOR ERRORS
	TLZE	S,IOW		;IN A WAIT?
	PUSHJ	P,SETIOD	;YES, UNWAIT US.
	TRNE	S,IODEND	;EOF?
	JRST	RDEOF		;YES.
	PUSHJ	P,WRDCNT	;COMPUTE # OF WORDS TRANSFERRED
	 TRO	S,IOBKTL	;NO SKIP IF RECORD TOO LONG
	HRRM	T2,1(T1)	;STORE WORD COUNT

INTERNAL FTSACCT
IFN FTSACCT,<
EXTERNAL PJOBN,JBAMT3
	LDB	J,PJOBN		;GET JOB NUMBER
	ADDM	T2,JBAMT3(J)
				;ACCUMULATE COUNT OF WORDS READ
>
	PUSHJ	P,ADVBFF	;ADVANCE BUFFERS-ADDRESS CHECK
	JRST	IOSTOP		;STOP READING
	TRNE	S,IOTEND!IODTER!IODERR!IOBKTL
	JRST	IOSTOP		;STOP IF ERROR
	HLRZ	U,USEWRD	;GET BACK COMMAND
	SOSG	QUANTM
	SKIPN	MTREQ
	JRST	MTIN1		;CONTINUE READING WHILE QUANTM POSITIVE
	JRST	IOSTOP		;STOP WHEN ANOTHER JOB WANTS CONTROL AND
				;QUANTM EXHAUSTED

RDEOF:	TRZ	S,IODEND
	TLO	S,IOEND
IOSTOP:	PUSHJ	P,CLRACT
	PUSHJ	P,RELCTL	;RELEASE CONTROLLER
	JRST	INTXIT		;EXIT THIS INTERRUPT.

INTWR:				;BUFFERED MODE WRITING
	JSR	ERRCK		;CHECK FOR ERRORS
	TLZE	S,IOW
	PUSHJ	P,SETIOD
ADVOUT:	PUSHJ	P,ADVBFE	;ADVANCE OUTPUT BUFFER
	JRST	IOSTOP		;NO MORE.
	TRNE	S,IOTEND!IODTER!IODERR!IOBKTL
	JRST	IOSTOP		;STOP IF ERROR
	HLRZ	U,USEWRD	;GET BACK COMMAND
	SOSG	QUANTM
	SKIPN	MTREQ
	JRST	MTOUT1		;CONTINUE WRITING WHILE QUANTM LASTS
	JRST	IOSTOP		;STOP AFTER QUANTM EXHAUSTED AND SOME JOB WAITING FOR CONTROL

INTDMP:				;DUMP MODE I/O
	JSR	ERRCK
	TRNN	S,IOTEND!IODTER!IODERR!IOBKTL
	JRST	DMPBLK		;GET NEXT RECORD
	JRST	DMPEND


INTSP:				;HERE FOR INTERRUPT ON SPACING MTAPE
	LDB	T1,[POINT 4,USEWRD,8]	;GET FUNCTION
	CAIN	T1,5		;IS IT WRITE EOF?
	JSR	ERRCK		;YES.CHECK FOR ERRORS
DMPEND:	TLZE	S,IOW
	PUSHJ	P,SETIOD
	JRST	IOSTOP		;TERMINATE THE OPERATION

ERRCK:	0			;SAVE RETURN
	TRNN	S,IODTER!IODERR!IOBKTL
	JRST	ERRCK2		;NO ERRORS
IFN TM10B,<
	SKIPN	CHNEWD
	CONSZ	MTS,CHANER
	JRST	CHNERR		;CHANNEL ERROR
>
	CONSO	MTS,ILLOP!HUNG!RCERR	;IS THIS ERROR CORRECTBALE?
	TRNE	S,IONRCK	;CAN WE TRY TO CORRECT?
	JRST	@ERRCK		;NO TO EITHER
ERRCK1:	TLNN	S,IO		;WRITING?
	JRST	READRC		;NO. READ RECOVERY
	SETZM	BLANKN		;CLEAR COUNT OF 3" BLANK SECTIONS

RETRY:	PUSHJ	P,LCALC		;RETRUN COUNT OF 3"
				;BLANK SECTIONS IN T1
	MOVEM	T1,BLANK3	;SECTIONS TO BLANK
	ADDB	T1,BLANKN
	CAIL	T1,↑D100	;100. 3" SECTIONS=25 FEET
	JRST	ERRXIT		;TRIED ENOUGH BLANK TAPE, GIVE ERROR
	JSR	BACKSP		;SPACE REVERSE OVER RECORD IN ERROR
WB.1:	HLRZ	U,USEWRD
	ANDI	U,760770
	IORI	U,015000	;WRITE 3" OF BLANK TAPE
	PUSHJ	P,MTEROP
	SOSLE	BLANK3		;ENOUGH WRITTEN?
	JRST	WB.1		;NO, CONTINUE

;DO THE ORIGINAL WRITE OPERATION OVER AGAIN

	MOVE	T1,SVPNTR
	MOVEM	T1,PNTR		;RESTORE IOWD
	HLRZ	U,USEWRD
	PUSHJ	P,MTEROP	;DO THE OPERATION
	AOS	REWRIT		;WRITE RETRYS
	TRNN	S,IODTER!IODERR	;ANY ERRORS
	JRST	RET.0		;NO, CHECK IT
	AOSGE	ERCNT		;TRIED ENOUGH?
	JRST	RETRY		;TRY TO WRITE AGAIN
	JRST	ERR.1		;EXIT WITH ERROR

;AT THIS POINT THE RECORD IS PRESUMABLY WRITTEN WITHOUT ERROR
;HOWEVER TO BE ASSURED OF THAT DO
; 2 BACKSPACES AND 2 DUMMY READ TO VERIFY THAT NO ERRORS OCCUR.

RET.0:	JSR	BACKSP
	JSR	BACKSP
	TRNN	S,IOBOT		;NOW AT LOAD POINT?
	JSR	ERREAD		;NO, READ PREVIOUS DATA
RET.2:	JSR	ERREAD		;READ THE BLOCK REWRITTEN
	MOVE	T1,DCOUNT	;COUNT OF WORDS
	SUBI	T1,NOISE
	TRNE	S,IODTER	;PARITY OR BAD TAPE?
	JUMPL	T1,RET.2	;YES-IGNORE AND TRY NEXT
				; TRYING TO PASS "NOISE" RECORD
	CONSZ	MTS,RCERR	;READ COMPARE ERROR?
	TRO	S,IODTER	;YES, MAKE IT LOOK LIKE A DATA ERROR
	HLRO	T1,SVPNTR
	MOVN	T1,T1		;PRESUMED LENGTH OF RECORD WRITTEN
	CAME	T1,DCOUNT	; = LENGTH JUST READ?
	JRST	ERRXIT		;NO. NOTE ERROR
	TRNE	S,IODTER!IODERR	;ERRORS?
	JRST	ERR.1		;NO RECOVERY
	AOS	WRTREC		;COUNT RECORD SUCCESSFULLY REWRITTEN
	MOVE	T1,INTSW1
	MOVEM	T1,INTSW	;RESTORE DISPATCH
	JRST	@INTSW		;DISPATCH TO ORIGINAL HANDLER

ERRXIT:	TRO	S,IODTER!IODERR	;INDICATE ERROR TO USER PROGRAM
ERR.1:	AOS	WFAIL		;COUNT RECOVERY FAILURE
	JRST	@ERRCK
;HERE TO RECOVER FROM A READ ERROR

READRC:	AOSL	ERCNT		;TRIED ENOUGH?
	JRST	READ.3		;YES EXIT WITH ERROR
	PUSHJ	P,WRDCNT	;COMPUTE RECORD LENGTH
	 JRST	READ.1		;RECORD LENGTH .GT. WORD COUNT
	CAIL	T2,NOISE	;CAN WE CALL IT A NOISE RECORD?
	JRST	READ.1		;NO
	AOS	NOISER		;COUNT NOISE RECORD
	JRST	READ.2		;FORGE AHEAD

READ.1:	JSR	BACKSP
READ.2:	MOVE	T1,SVPNTR
	MOVEM	T1,PNTR		;RESTORE IOWD
	HLRZ	U,USEWRD
	PUSHJ	P,MTEROP	;DO THE READ AGAIN
	AOS	REREAD		;COUNT REREAD ATTEMPTS
	MOVE	T1,INTSW1
	MOVEM	T1,INTSW	;RESTORE DISPATCH(SAVED AT MTDTGO)
	JRST	@INTSW		;DISPATCH TO ORIGINAL HANDLER
READ.3:	AOS	RFAIL		;COUNT REREAD FAILURES
	JRST	@ERRCK
ERREAD:	0
IFE TM10B,<
	MOVE	T1,[JSR DUMMY]
	EXCH	T1,MTALOC
	MOVEM	T1,SVBLKI	;SET FOR "NULL" READ
	SETZM	DCOUNT		;PREPARE TO COUNT WORDS
	HLRZ	U,USEWRD
	ANDI	U,760777	;LEAVE DATA PI
	IORI	U,002000	;FUNCTION=READ
	PUSHJ	P,MTEROP
	MOVE	T1,SVBLKI
	MOVEM	T1,MTALOC	;RESTORE BLKI/BLKO
>
IFN TM10B,<
	MOVE	T1,SVPNTR
	MOVEM	T1,PNTR		;RESTORE IOWD FOR DATA
	MOVEI	T1,CPNTR
	MOVEM	T1,MTIOC	;USE DIFFERENT CHANNEL COMMAND LIST
	HLRZ	U,USEWRD
	ANDI	U,760770	;NO DATA PI
	IORI	U,003000	;FUNCTION=READ/COMPARE
	PUSHJ	P,MTEROP
	PUSHJ	P,WRDCNT
	 JFCL
	MOVEM	T2,DCOUNT	;STORE RECORD LENGTH AS THO COUNTED UP
	MOVEI	T1,PNTR
	MOVEM	T1,MTIOC	;RESTORE NORMAL CCW LIST
>
	JRST	@ERREAD

DUMMY:	0			;HERE TO READ A RECORD TO CHECK
				;FOR LENGTH AND ANY ERRORS
	DATAI	MTC,SINK
	AOS	DCOUNT
	JEN	@DUMMY

MTEROP:	POP	P,INTSW		;RETURN TO MTEROP CALLER
				;ON DONE INTERRUPT
	JRST	MTCGO		;DO OPERATION AND EXIT THIS INTERRUPT

BACKSP:	0
IFE TM10B,<
	MOVE	T1,[JSR MTDEND]	;SET FOR POSITIVE STOP OF BACKSPACE
	EXCH	T1,MTALOC
	MOVEM	T1,SVBLKI
	HLRZ	U,USEWRD
	ANDI	U,760777	;LEAVE DATA PI FOR STOPPING
>
IFN TM10B,<
	HLRZ	U,USEWRD
	ANDI	U,760770	;NO DATA PI
	SETZM	PNTR		;STOP WITH NO DATA TRANSFER
>
	IORI	U,007000
	PUSHJ	P,MTEROP	;ISSUE BACKSPACE
IFE TM10B,<
	MOVE	T1,SVBLKI
	MOVEM	T1,MTALOC	;RESTORE BLKI
>
	JRST	@BACKSP
;CALCULATE NUMBER OF 3" SECTIONS OF BLANK TAPE TO 
;WRITE TO COVER RECORD IN ERROR

LCALC:	LDB	T2,[POINT 2,USEWRD,11]	;GET DENSITY (0,1,2,3)
	HLRZ	T1,LTABLE(T2)	;ASSUME 7 CHANNEL
	CONSO	MTS,CHAN7	;SEVEN CHANNEL TAPE?
	HRRZ	T1,LTABLE(T2)	;NO. 9 CHANNEL
	MOVE	T2,T1		;COPY ENTRY
	HLRZ	T1,USEWRD	;GET COMMAND
	TRNE	T1,1B22		;CORE DUMP MODE?
	MOVEI	T2,↑D600	;YES. 600. WORDS/3"
	HLRO	T1,SVPNTR
	MOVNS	T1,T1		; # OF WORDS IN RECORD
	IDIV	T1,T2		; / WORDS-3"
	ADDI	T1,1		;ROUND UP
	CAILE	T1,↑D10	
	MOVEI	T1,↑D10		;ALLOW ONLY 30" BLANK TAPE PER CALL
				; SO 25' LIMIT NOT EXCEEDED BY MTTRY RETRIES
	POPJ	P,

LTABLE:	XWD	↑D100,↑D120	;7 CHANNEL,9 CHANNEL WORDS/3" OF TAPE
	XWD	↑D278,↑D333	;556 BPI
	XWD	↑D400,↑D480	;800 BPI
	XWD	↑D400,↑D480	;800 BPI

IFN TM10B,<
;HERE ON CHANNEL ERROR

CHNERR:	CONI	MTS,U		;READ ERROR BITS
	TLNN	U,(DTPAR)	;DATA PARITY ERROR?
	JRST	REFRNS		;NO, CONTROL WORD HAS BEEN STORED
	CONO	MTS,21		;YES, CLEAR ERR BIT, SET JOB DONE
	SETOM	CHNEWD		;FLAG DATA PARITY ERR
	POPJ	P,		;AND EXIT INTERRUPT. WILL COME BAKC
				;LATER ON JOB-DONE INTERRUPT

;HERE ON A CHANNEL ERROR AFTER THE CHANNEL CONTROL WORD IS WRITTEN
;IT IS ASSUMED THAT THE PAR OR NXM STOP SWITCHES ARE DOWN, SO
;REFERNCING THE WORD WHICH THE CHANNEL SAYS IS BAD SHOULD
;CAUSE THE MACHINE TO HALT - IF IT DOESN'T, LIGHT ERROR BIT AND GO AWAY

REFRNS:	CONO	MTS,10		;CLEAR ERROR BITS
	MOVE	T1,MTCCW	;CHANNEL CONTROL WORD
	PUSHJ	P,REFREN##	;REFERENCE THE BAD WORD
	JRST	ERRCK1		;MUST BE A PORT PROBLEM - RETRY
>
;MORE ERROR CODE

ERRCK2:
IFE TM10B,<
IFN MTRRCK,<			;THIS IS THE RE-READ CODE.
	JRST	@ERRCK		;NOP THIS CODE FOR NOW
	MOVNI	T1,MTTRY
	TLNN	S,RRCHK		;DOES USER WANT RE-READ CHECK ALWAYS?
	CAME	T1,ERCNT	;WAS THERE AN ERROR?
	TRNE	S,IODEND	;YES, EOF?
	JRST	@ERRCK		;RECORD IS OK.
	JSR	BACKSP
	MOVSI	T1,(BLKO MTC,0)
	HLLM	T1,MTALOC	;SET UP MTALOC FOR REREAD
	MOVE	T1,SVPNTR
	MOVEM	T1,PNTR		;RESTORE PNTR
	HLRZ	U,USEWRD
	ANDI	U,760777	;LEAVE DATA PI
	IORI	U,3000		;READ-COMPARE
	PUSHJ	P,MTEROP
	CONSZ	MTS,RLINC	;THE RE-READ RECORD BETTER BE THE
	TRO	S,IOBKTL	;SAME LENGTH AS THE ORIGINAL!
	MOVSI	T1,(BLKI MTC,0)
	TLNN	S,IO		;RESTORE MTALOC IF NECESSARY
	HLLM	T1,MTALOC
	MOVE	T1,INTSW1	;PUT BACK INTERRUPT SWITCH
	MOVEM	T1,INTSW

;IF THERE ARE ANY ERROR BITS, CONSIDER THEM UNCORRECTABLE.

>
>	;END TM10B CONDITIONAL
	JRST	@ERRCK

EXTERNAL WAIT1
MTDMPI:	PUSHJ	P,DLYCTL	;DUMP INPUT
	TLZ	S,IO
	JRST	MTDMP1
MTDMPO:	PUSHJ	P,DLYCTL	;DUMP OUTPUT
	TLO	S,IO
MTDMP1:	HRLM	U,USEWRD	;SAVE U
	HRLI	M,R
	SETZM	BADCOM		;CLEAR ERROR FLAG ON UUO CALL ENTRY
	PUSHJ	P,MT3XCH	;SAVE ACS
	PUSHJ	P,COMCHK	;SET UP USER LIMITS - GET AND TEST FIRST IOWD
	PUSHJ	P,MT3XCH	;SAVE USER LIMIT, GOOD/BAD FLAG-RESTORE ACS
	SKIPE	BADCOM		;WAS THERE ANY ERROR?
	JRST	ADRXIT		;YES. GO REPORT IT
	SETOM	LVFLAG		;FLAG US AS BEING AT UUO LEVEL
	TLNE	S,IO		;CHECK WRITE LOCK
	CONSO	MTS,EOT!WRLK	;AND EOT IF WRITING
	JRST	MTDMP2
	CONSO	MTS,EOT		;ERROR
WRLOCK:	TROA	S,IOIMPM	;WRITE LOCK
	TRO	S,IOTEND+IOBKTL	;EOT
	JRST	RELTAP		;GIVE UP TAPE AND RETURN

ADRXIT:	PUSHJ	P,RELTAP	;GIVE UP CONTROLLER
	JRST	ADRERR		;AND REPORT BAD COMMAND LIST
MT3XCH:	EXCH	T2,MJOTOP	;SAVE ACS + GET BOUNDRIES
	EXCH	T3,MJOBOT	;SET UP BY COMCHK
	EXCH	S,BADCOM	;AND ERROR FLAG
	POPJ	P,		;SECOND CALL SAVES FLAGS AND RESTORES ACS

MTDMP2:	SOS	M		;WILL COUNT IT UP LATER
	MOVEM	M,LSTLOC	;SAVE LOC OF LIST(R IN INDEX FIELD)
DMPBLK:	PUSHJ	P,NXTCOM	;GET NEXT COMMAND

INTERNAL FTSACCT
IFN FTSACCT,<
EXTERNAL JBAMT3,PJOBN
	HLRO	T2,T1		;-WORD COUNT
	MOVNS	T2		;+WORD COUNT
	LDB	J,PJOBN		;GET JOB NUMBER
	ADDM	T2,JBAMT3(J)	;ACCUMULATE COUNT OF WORDS XFERRED
>
	ADDI	T1,(R)		;ADD RELOCATION FACTOR
	MOVEI	T2,INTDMP
	MOVEM	T2,INTSW	;SET INTERRUPT SWITCH
	HLRZ	U,USEWRD	;RESTORE U
	TLNE	S,IO		;WRITING?
	JRST	MTOUT2		;YES. GO WRITE RECORD
	TRNN	S,1		;MODE 16?
	TRO	U,10000		;YES(DR)- READ ACROSS RECORD BOUNDARIES(FUNC 2 CHANGE TO 12)
	JRST	MTIN2		;GO READ RECORD

EXTERNAL NXCMR,PBUFSZ
NXTCOM:	SKIPE	T1,REMNDR	;PARTIAL IOWD LEFT TO DO?
	JRST	NXTCM3		;YES, CONTINUE WITH IT
	PUSHJ	P,MT3XCH	;SAVE ACS-GET FLAG AND LIMITS
	EXCH	M,LSTLOC	;GET POINTER TO CURRENT IOWD
	PUSHJ	P,NXCMR		;GET AND CHECK NEXT IOWD
	PUSHJ	P,MT3XCH	;SAVE RESULTS-RESTORE ACS
	EXCH	M,LSTLOC	;SAVE POINTER-RESTORE AC
	JUMPL	T1,NXTCM2	;REAL COMMAND
	POP	P,T1		;0 - THROUGH
	JRST	DMPEND

	EXTERN	MMTSIZ		;-MTSIZ
NXTCM2:	TLNE	S,IO		;WRITING?
	TRNE	S,1		;MODE 16?
	POPJ	P,		;NO. USE IOWD AS OBTAINED
NXTCM3:	SETZM	REMNDR
	LDB	U,PBUFSZ	;GET BLOCK SIZE FROM DDB
	MOVNI	U,-1(U)		;U=MINUS BLOCKSIZE
	HLRE	T2,T1		;GET WORD COUNT FROM IOWD
	CAML	T2,U		;WORD COUNT TOO LARGE?
	POPJ	P,		;NO, GO DO IT
	MOVN	U,U		;U=BLOCKSIZE
	HRL	U,U		;U=BLOCKSIZE, BLOCKSIZE
	ADD	T1,U		;CORRECT IOWD FOR NEXT TRANSFER
	MOVEM	T1,REMNDR	;AND SAVE FOR NEXT RECORD
	SUBI	T1,(U)		;ADDRESS FOR THIS IOWD
	MOVN	U,U		;U=-BLOCKSIZE, -BLOCKSIZE
	HRL	T1,U		;WRITE -BLOCKSIZE WORD RECORD
	POPJ	P,		;RETURN CORRECTED IOWD
REMNDR:	0

WRDCNT:	HRRZ	T1,SVPNTR	;ADDRESS OF FIRST WORD (-1)
IFE TM10B,<
	HRRZ	T2,PNTR		;ADDRESS OF LAST WORD TRANSMITTED
	SUB	T2,T1		;LAST LOC. - FIRST
	CONSO	MTS,RLINC	;RECORD LENGTH=REQUEST?
	JRST	WRDC1		;YES
	HLRZ	T1,PNTR		;GET RESIDUE OF WORD COUNT
	SKIPE	T1		;IS IT 0?
WRDC1:	AOS	(P)		;NO. RECORD LENGTH .LE. WORD COUNT
	MOVEI	T1,@DEVIAD(F)
	POPJ	P,		;NO SKIP IF LONG RECORD
>
IFN TM10B,<
	HRRZ	T2,MTCCW	;GET ADDRESS OF LAST WORD TRANSMITTED
	SUB	T2,T1		;LAST LOC. - FIRST
	CONSO	MTS,RLINC	;RECORD LENGTH=REQUEST?
	JRST	WRDC1		;YES
	SOS	T2		;T2=LAST ADDRESS
	HLRZ	T1,MTCCW	;GET DF10 CCW ADDRESS
	CAIN	T1,PNTR+1	;DID DF10 DISCONNECT BECAUSE
				;WORD COUNT .LT. RECORD LENGTH?
WRDC1:	AOS	(P)		;NO. RECORD LENGTH .LE. WORD COUNT
	MOVEI	T1,@DEVIAD(F)
	POPJ	P,
>

IFN FT5UUO,<			;MISC 5 SERIES UUO?
;MTCHR. UUO -- RETURN MAG-TAPE CHARACTERISTICS
;CALL:	MOVE AC,DEVICE OR CHANNEL
;	MTCHR. AC,
;	ERROR
;	OK
;ERROR RETURN IF NOT IMPLEMENTED (AC UNCHANGED)
;	AC=-1 IF NO DEVICE OR NOT MT
;OK RETURN IF MT WITH AC:
;	BIT 0-33 (FUTURE)
;	    34-35: 1=200 BPI, 2=556, 3=800

	INTERN	MTACHR
	EXTERN	DVCNSG,STOTC1,RTM1
MTACHR:	PUSHJ	P,DVCNSG	;FIND DEVICE
	  JRST	RTM1		;NOT THERE -- GIVE -1
	MOVSI	T1,DVMTA	;GET MTA TYPE
	TDZN	T1,DEVMOD(F)	;IS IT MTA? (CLEAR T1)
	JRST	RTM1		;NO -- GIVE -1
	MOVE	S,DEVIOS(F)	;GET STATUS
	TLNE	S,COMPAT	;IBM MODE?
	JRST	MTACD1		;YES -- FORCE 800
	LDB	T1,[POINT 2,S,28]
	JUMPN	T1,MTACD2	;USE INIT DENSITY
	LDB	T1,[POINT 2,S,10]
	JUMPN	T1,MTACD2	;USE COMMAND DENSITY
	TROA	T1,STDENS	;USE INSTALLATION DENSITY
MTACD1:	MOVEI	T1,3		;FORCE 800
MTACD2:	JRST	STOTC1		;RETURN ANSWER
>	;END CONDITIONAL ON FT5UUO

IFE FT5UUO,<
XP	MTACHR,CPOPJ
>
USEWRD:	0		;LH STORE COMMAND ISSUED BY CONO MTC,
			;RH STORES STATUS READ IT AT MTAINT

USEPRG:	0		;COPY OF R FOR USER WITH CONTROL

ERCNT:	0		;RETRY COUNTER, -3,-2,-1,0,...10

QUANTM:	0		;COUNTED DOWN ON CONSECUTIVE READS OR WRITES
LSTLOC:	0
IFN TM10B,<
CPNTR:	IOWD	1,[EXP 0]	;EXTRA ZERO WORD FOR READ/COMPARE
			; MUST IMMEDIATELY PRECEDE PNTR
>
PNTR:	0		;BLKI/BLKO POINTER WORD OR
			;FIRST WORD OF DF10 CHANNEL COMMAND PROGRAM
IFN TM10B,<		;THIS MUST FOLLOW PNTR
		EXP .+1	;LEAVE AN EXTRA COMMAND WORD FOR SHORT
			;OR LONG RECORD TEST
	0		;END OF CHANNEL COMMAND LIST
>

SVPNTR:	0		;COPY OF IOWD
SVBLKI:	0		;COPY OF BLKI/BLKO SAVED BY ERREAD
SINK:	0		;PLACE TO STUFF DATA
DCOUNT:	0		;COUNT OF WORDS READ BY ERREAD
NOISER:	0		;COUNT OF NOISE RECORDS IGNORED
BLANKN:	0		;TOTAL NUMBER OF 3" TO BLANK
BLANK3:	0		;COUNT OF 3" TO BLANK
INTSW:	0		;DISPATCH ADDRESS- INTIGN,INTRD,INTWR,INTSP,...
INTSW1:	0		;COPY OF ORIGINAL DISPATCH(BEFORE ERROR)
IFN TM10B,<
CHNEWD:	0		;-1 IF SAW A CHAN DATA PARITY ERR
>
;DUMP MODE IO CONTROL FLAGS

MJOTOP:	0		;UPPER LIMIT OF USER AREA
MJOBOT:	0		;LOWER LIMIT OF USER AREA
BADCOM:	0		;ERROR FLAG
LVFLAG:	0		;-1 IF UUO LEVEL AND DUMP MODE I/O

INTERN CNIMTC,CNIMTS,CNOMTC

CNIMTC:	0		;STATUS AFTER LAST INTERRUPT
CNIMTS:	0		;RESULT OF LAST SETST
CNOMTC:	0		;LAST COMMAND ISSUED AT MTCGO

INTERN HNGFNC,RECCNT,MTSERR,MTSCNT

HNGMTS:	0		;STATUS WHEN DRIVE HUNG
HNGMTC:	0
HNGFNC:	0		;0-17 FUNCTION HUNG RECOVERY ATTEMPTED ON
RECCNT:	0		;COUNTER OF HUNG TIMEOUTS
MTSERR:	0		;CONI FOLLOWING LAST TAPE ERROR
MTSCNT:	0		;COUNT OF TAPE ERRORS-ALL XPORTS

;RECOVERY ATTEMPT COUNTERS

REWRIT:	0		;COUNT OF REWRITES
WFAIL:	0		;COUNT OF RECORDS UNWRITEABLE
WRTREC:	0		;COUNT OF RECORDS REWRITTEN SUCCESSFULLY
REREAD:	0		;COUNT OF REREAD OPERATIONS
RFAIL:	0		;COUNT OF RECORDS UNREADABLE
IFN FTTRACK,<
INTERN TIMHNG
TIMHNG:	0		;TIME IN JIFFIES WHN LAST REC. ATTEMPTED
>

	LIT
MTAEND:	END